#include <string>
#include <iostream>
#include <sys/types.h>
#include "error.hpp"
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>
void usage(const std::string proc)
{
    std::cout << "Usage " << proc << " severip serverport" << std::endl;
}
void *recv(void *arg)
{
    // 收消息
    int socket_ = *((int *)arg);
    while (true)
    {
        char buffer[1024] = {0};
        int n = read(socket_, buffer, sizeof(buffer) - 1);
        if (n > 0)
        {
            buffer[n] = '\0';
            std::cout << "server echo# " << buffer << std::endl;
        }
        else if (n == 0)
        {
            close(socket_);
            std::cout << "server quit" << std::endl;
        }
        else
        {
            close(socket_);
            std::cout << "client read err" << strerror(errno) << std::endl;
            exit(READ_ERR);
        }
    }
}
int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        usage(argv[0]);
        std::cout << "stage error" << strerror(errno) << std::endl;
        exit(USAGE_ERR);
    }
    const std::string ip_ = argv[1];
    u_int16_t port = atoi(argv[2]);

    int socket_ = socket(AF_INET, SOCK_STREAM, 0);
    if (socket_ < 0)
    {
        std::cout << "create socket error" << strerror(errno) << std::endl;
        exit(SOCKET_ERR);
    }
    std::cout << "create socket successs" << std::endl;
    // 打开网络文件

    // 不用客户端自己绑定端口号和ip地址
    struct sockaddr_in sock;
    sock.sin_addr.s_addr = inet_addr(ip_.c_str()); // 将字符串类型的地址转为四字节地址,而且是网络字节序了
    sock.sin_port = htons(port);
    sock.sin_family = AF_INET;
    int len = sizeof(sock);
    // 开始连接
    int timenum = 5;
    while (connect(socket_, (sockaddr *)&sock, len) < 0)
    {
        sleep(1);
        std::cout << "开始重连:" << std::endl;
        timenum--;
        if (timenum == 0)
            break;
    }
    if (timenum <= 0)
    {
        std::cout << "链接失败" << std::endl;
        exit(CON_ERR);
    }
    pthread_t id;
    pthread_create(&id,nullptr,recv,&socket_);
    while (true)
    {
        std::string msg;
        std::cout << "客户端# "<<std::endl;
        getline(std::cin, msg);
        write(socket_, msg.c_str(), msg.size());
    }
    return 0;
}